-- 定义一个用于随机化数组的函数
函数 随机化数组(t)
    因为 i = #t, 2, -1 做
        局部 j = 数.random(i)
        t[i], t[j] = t[j], t[i]
    结束
结束

-- 使用模块化方法定义游戏类
局部 二十一点 = {}
二十一点.__index = 二十一点

-- 初始化游戏对象
函数 二十一点.新()
    局部 游戏 = 设元({
        牌叠 = {},       -- 一副新朴克牌
        玩家 = {{}, {}}, -- 闲家和庄家
        当前玩家 = 1, -- 当前玩家
        闲家点数 = 0, -- 闲家点数
        庄家点数 = 0, -- 庄家点数
        输入值 = "",
    }, 二十一点)
    游戏:洗牌() -- 初始化洗牌
    返回 游戏
结束

-- 洗牌
函数 二十一点:洗牌()
    self.牌叠 = {}
    因为 花色, 序数 属于 匹配({['梅花'] = {1,2,3,4,5,6,7,8,9,10,11,12,13}, ['方块'] = {1,2,3,4,5,6,7,8,9,10,11,12,13}, ['红桃'] = {1,2,3,4,5,6,7,8,9,10,11,12,13}, ['黑桃'] = {1,2,3,4,5,6,7,8,9,10,11,12,13}}) 做
        因为 _, 点数 属于 序配(序数) 做
            表.insert(self.牌叠, {花色 = 花色, 点数 = 点数})
        结束
    结束
    数.randomseed(系统.time()) -- 初始化随机数生成器
    随机化数组(self.牌叠) -- 使用函数随机化表
结束

-- 发牌
函数 二十一点:发牌(玩家, 明牌)
    局部 手牌 = 表.remove(self.牌叠, 1)
    表.insert(玩家, 手牌)
    如果 明牌 即
        输出((玩家 == self.玩家[1] 与 "闲家" 或 "庄家").."手牌 " .. 手牌.花色 ..', '.. 手牌.点数)
    结束
结束

-- 计算点数
函数 二十一点:计算点数(玩家)
    局部 合计 = 0
    局部 尖儿 = 假
    因为 _, 手牌 属于 序配(玩家) 做
        如果 手牌.点数 > 10 即
            合计 = 合计 + 10
        否则
            合计 = 合计 + 手牌.点数
        结束
        如果 手牌.点数 == 1 即
            尖儿 = 真
        结束
    结束
    如果 尖儿 与 合计 < 12 即
        合计 = 合计 + 10
    结束
    返回 合计
结束

-- 闲家发牌逻辑 (闲家操作) 判断游戏是否结束
函数 二十一点:游戏结束吗()
    self.闲家点数 = self:计算点数(self.玩家[1])
    如果 self.闲家点数 > 21 即
        返回 真
    结束
    返回 假
结束

-- 检查玩家是否停牌，并处理相关逻辑
函数 二十一点:要牌吗()
    输出("请选择：h-要牌，s-停牌，b-重新开始，q-退出")
    self.输入值 = 端口.read("*line")
    如果 self.输入值 == "h" 即
        self:发牌(self.玩家[self.当前玩家], 真)
    要么 self.输入值 == "s" 即
        如果 self.当前玩家 == 1 即
            self.当前玩家 = 2 -- 更改为庄家回合
        结束
    要么 self.输入值 == "b" 即
        --self:洗牌()
        --self.当前玩家 = 1
        self:新游戏()
        输出("-----------------再来!--------------")
    要么 self.输入值 == "q" 即
        闲家点数 = "虚"
        庄家点数 = "虚"   
        系统.exit() -- 退出程序
    否则
        输出("无效输入，请重新输入。")
        返回 假
    结束
    返回 假
结束

-- 庄家发牌逻辑 (电脑自动操作)
函数 二十一点:庄家发牌()
    当 self:计算点数(self.玩家[2]) < 17 做
        self:发牌(self.玩家[2], 假) -- 不显示庄家手牌
    结束
结束

-- 添加一个用于统一打印玩家手牌的函数
函数 二十一点:开牌()
    输出("\n闲家手牌：")
    因为 _, 手牌 属于 序配(self.玩家[1]) 做
        输出(手牌.花色 .. ', ' .. 手牌.点数)
    结束

    输出("\n庄家手牌：")
    因为 _, 手牌 属于 序配(self.玩家[2]) 做
        输出(手牌.花色 .. ', ' .. 手牌.点数)
    结束

结束

-- 此函数用于计算并显示二十一点游戏中的玩家和庄家的点数
函数 二十一点:合计点数()
    -- 输出闲家的点数
    输出("\n闲家点数", self.闲家点数)
    
    -- 计算庄家的点数，使用玩家数组中的第二个元素（庄家）进行计算
    self.庄家点数 = self:计算点数(self.玩家[2])

    -- 输出庄家的点数
    输出("庄家点数", self.庄家点数)

    -- 显示游戏进行中的提示信息，允许玩家选择重新开始或退出游戏
    输出('--------------------b-重新开始!--------------------q-退出游戏!--------------------')

结束     


-- 游戏主循环
函数 二十一点:开局()
    self:发牌(self.玩家[1], 真) -- 给闲家发第一张牌并显示
    self:发牌(self.玩家[1], 真) -- 给闲家发第二张牌并显示
    self:发牌(self.玩家[2], 假) -- 给庄家发第一张牌（不显示）
    self:发牌(self.玩家[2], 真) -- 给庄家发第二张牌并显示

    当 self.当前玩家 == 1 与 非 self:游戏结束吗() 做
        self:要牌吗() -- 玩家选择是否要牌
    结束


    如果 self.闲家点数 > 21 即

        -- 在闲家爆牌或停牌后展示闲家和庄家的所有牌
        self:开牌() -- 展示所有玩家手牌

        self:合计点数() -- 展示所有玩家点数

        输出("闲家爆牌，庄家赢")


    否则
        self:庄家发牌() -- 庄家自动发牌到点数达到17或以上

        self:开牌() -- 展示所有玩家手牌

        self:合计点数() -- 展示所有玩家点数

        -- 判断胜负
        如果 self.庄家点数 > 21 即
            输出("庄家爆牌，闲家赢")
        要么 self.闲家点数 > self.庄家点数 即
            输出("闲家赢")
        要么 self.庄家点数 > self.闲家点数 即
            输出("庄家赢")
        否则
            输出("平局")
        结束
    结束

    self.输入值 = 端口.read("*line") -- 读取玩家输入
    如果 self.输入值 == "b" 即
        self:新游戏() -- 如果输入b，则重新开始游戏
    结束
    
结束

-- 重新开始游戏
函数 二十一点:新游戏()
    self:洗牌() -- 重新洗牌
    self.玩家[1] = {} -- 重置闲家手牌
    self.玩家[2] = {} -- 重置庄家手牌
    self.当前玩家 = 1
    输出("--------------------再来!--------------------")
    self:开局() -- 开始新一局游戏
结束

-- 初始化游戏并开始
局部 游戏 = 二十一点.新()
游戏:开局()